package com.zzg.mybatis.generator.util;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.MessageFormat;
import java.text.NumberFormat;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 字符串处理工具类
 */
public class StringUtil{
	
	/**
	 * 将字符串从斜线样式转换为驼峰样式，例如 my_course 将转换为 MyCourse
	 * @param str
	 * @return
	 */
	public static String dbStringToCamelStyle(String str) {
        if (str != null) {
            str = str.toLowerCase();
            StringBuilder sb = new StringBuilder();
            sb.append(String.valueOf(str.charAt(0)).toUpperCase());
            for (int i = 1; i < str.length(); i++) {
                char c = str.charAt(i);
                if (c != '_') {
                    sb.append(c);
                } else {
                    if (i + 1 < str.length()) {
                        sb.append(String.valueOf(str.charAt(i + 1)).toUpperCase());
                        i++;
                    }
                }
            }
            return sb.toString();
        }
        return null;
    }
	
	/**
	 * 自定义生成的实体类格式(首字母大写其余小写+suffix)
	 * @param tableName 表名
	 * @param suffix 后缀
	 * @return
	 */
	public static String customClassName(String tableName,String suffix){
		char[] table_name = tableName.toLowerCase().toCharArray();
		table_name[0]-=32;
        return String.valueOf(table_name).concat(suffix);
	}
	
	/**
	 * 空转换
	 * @param str
	 * @return
	 */
	public static String priseString(Object str) {
		if (str == null) {
			str = "";
		}
		return str.toString();
	}
	
	/**
	 * 验证是否为null,并转换成金额保留小数2位
	 * @param str
	 * @return
	 */
	public static String priseMoney(Object str) {
		if (str == null || str.equals("")) {
			return "";
		}
		DecimalFormat df = new DecimalFormat("0.##");
		return (df.format(str)).toString();
	}

	/**
	 * 判断字符串是否为数字
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isNum(String str) {
		if(str == null || "".equals(str)){
			return false;
		}
		return str.matches("^[-+]?(([0-9]+)([.]([0-9]+))?|([.]([0-9]+))?)$");
	}

	/**
	 * 验证是否为手机号
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isMobile(String str) {
		try {
			if (str == null || str.equals(""))
				str = "";
			else {
				str = new DecimalFormat("0").format(new Double(str));
			}
			String regExp = "^1[3|4|5|8|9]\\d{9}$";
			// String regExp = "^[1]([3][0-9]{1}|59|58|88|89)[0-9]{8}$";
			Pattern p = Pattern.compile(regExp);
			Matcher m = p.matcher(str);
			return m.find();
		} catch (Exception e) {
			return false;
		}
	}

	/**
	 * 将 Long/Double 数据 整数位前面补 位 例如: 31 补位后变成 0031 数据.
	 * 
	 * @param num
	 *            Long 被格式化前的数据
	 * @param formatStr
	 *            需要 格式化的数据样式
	 * @return
	 */
	public static String numberFillDigit(Object num, String formatStr) {
		if (!isNumeric(num + "")) {
			return num + "";
		}
		NumberFormat formatter = NumberFormat.getNumberInstance();
		int bit = formatStr.length();
		formatter.setMinimumIntegerDigits(bit);
		formatter.setGroupingUsed(false);
		String resStr = formatter.format(Double.parseDouble(num + ""));
		return resStr;
	}

	/**
	 * 判断是否为数字
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isNumeric(String str) {
		Pattern pattern = Pattern.compile("[0-9.]*");
		return pattern.matcher(str).matches();
	}

	/**
	 * 将数组转换成字符串，用,号隔开
	 * 
	 * @param str
	 * @return
	 */
	public static String arrayToString(Object[] arr) {
		String str = "";
		if (arr == null || arr.length == 0) {
			return str;
		}
		for (int i = 0; i < arr.length; i++) {
			str += (str.equals("")) ? arr[i] : "," + arr[i];
		}
		return str;
	}

	/**
	 * 将数字转换成数字序号 如：将1装换成① 暂时只支持1~10
	 * 
	 * 
	 */
	public final static HashMap<Object, Object> transitionNumber = new HashMap<Object, Object>();
	static {
		transitionNumber.put(1, "①");
		transitionNumber.put(2, "②");
		transitionNumber.put(3, "③");
		transitionNumber.put(4, "④");
		transitionNumber.put(5, "⑤");
		transitionNumber.put(6, "⑥");
		transitionNumber.put(7, "⑦");
		transitionNumber.put(8, "⑧");
		transitionNumber.put(9, "⑨");
		transitionNumber.put(10, "⑩");
	}

	/**
	 * 将对象转换成Map
	 * 
	 * @param arr
	 * @return
	 */
	public static HashMap<String, Object> classToMap(Object obj) {
		HashMap<String, Object> map = new HashMap<String, Object>();
		// 获取f对象对应类中的所有属性域
		Field[] fields = obj.getClass().getDeclaredFields();
		for (int j = 0, len = fields.length; j < len; j++) {
			String varName = fields[j].getName();
			try {
				// 获取原来的访问控制权限
				boolean accessFlag = fields[j].isAccessible();
				// 修改访问控制权限
				fields[j].setAccessible(true);
				// 获取在对象f中属性fields[i]对应的对象中的变量
				Object o = fields[j].get(obj);
				map.put(varName, o);
				// 恢复访问控制权限
				fields[j].setAccessible(accessFlag);
			} catch (IllegalArgumentException ex) {
				ex.printStackTrace();
			} catch (IllegalAccessException ex) {
				ex.printStackTrace();
			}
		}
		return map;
	}

	/**
	 * 判断是否是一个中文汉字
	 * 
	 * @param c
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static boolean isChineseChar(char c) throws UnsupportedEncodingException {
		// 如果字节数大于1，是汉字
		// 以这种方式区别英文字母和中文汉字并不是十分严谨，但在这个题目中，这样判断已经足够了
		return String.valueOf(c).getBytes("GBK").length > 1;
	}

	/**
	 * 按字节截取字符串
	 * 
	 * @param orignal
	 * @param beginIndex
	 * @param endIndex
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String substringByte(String orignal, int beginIndex, int endIndex) throws UnsupportedEncodingException {
		// 原始字符不为null，也不是空字符串
		if (orignal != null && !"".equals(orignal)) {
			// 将原始字符串转换为GBK编码格式
			orignal = new String(orignal.getBytes(), "GBK");
			// 要截取的字节数大于0，且小于原始字符串的字节数
			if (endIndex < beginIndex) {
				endIndex = orignal.getBytes("GBK").length;
			}
			StringBuffer buff = new StringBuffer();
			char c;
			for (int i = 0; i < endIndex; i++) {
				c = orignal.charAt(i);
				if (i >= beginIndex) {
					buff.append(c);
				}
				if (isChineseChar(c)) {
					// 遇到中文汉字，截取字节总数减1
					beginIndex--;
					endIndex--;
				}
			}
			return buff.toString();
		}
		return orignal;
	}

	/**
	 * 获得0-9,a-z,A-Z范围的随机数
	 * 
	 * @param length
	 *            随机数长度
	 * @return String
	 */

	public static String getRandomChar(int length) {
		char[] chr = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
		Random random = new Random();
		StringBuffer buffer = new StringBuffer();
		for (int i = 0; i < length; i++) {
			buffer.append(chr[random.nextInt(62)]);
		}
		return buffer.toString();
	}

	public static String getRandomChar() {
		return getRandomChar(10);
	}

	/**
	 * 将字符串分割，最后一个字符串可以包含任意个分隔符
	 * 如		String a = "183:0.28:233:1::::::::::::::";
	 * 			System.out.println(Arrays.toString(safeSplit(a, ":", 4)));
	 * 结果 		[183, 0.28, 233, 1::::::::::::::]
	 * @param str
	 * @param spliter
	 * @param length
	 * @return
	 */
	public static String[] safeSplit(String str, String spliter, int length) {
		if (length <= 1) {
			throw new RuntimeException("lengh必须大于1");
		}
		int[] index = new int[length - 1];
		String[] arr = new String[length];
		index[0] = str.indexOf(spliter);
		arr[0] = str.substring(0, index[0]);
		for (int i = 1; i < length - 1; i++) {
			index[i] = str.indexOf(spliter, index[i - 1] + 1);
			arr[i] = str.substring(index[i - 1] + 1, index[i]);
		}
		arr[length-1] = str.substring(index[length - 2] + 1);
		return arr;
	}

	/**
	 * 获取随机字符串
	 * @param length
	 * @return
	 */
	public static String getRandom(int length){
		String allChar = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		StringBuffer sb = new StringBuffer();
		Random random = new Random();
		for (int i = 0; i < length; i++) {
			sb.append(allChar.charAt(random.nextInt(allChar.length())));
		}
		return sb.toString();
	}

	/**
	 * 字符串中字符替换
	 * @param originStr 原始字符串
	 * @param replaceMap key-存在字符,value-新的字符
	 * @return
	 */
	public static String formatFormString(String originStr,Map<String,String> replaceMap){
		if("".equals(originStr) || originStr == null){
			return "";
		}
		String tempStr = originStr;
		if(replaceMap != null && replaceMap.size()>0){
			for(Map.Entry<String,String> m:replaceMap.entrySet()){
				tempStr = tempStr.replace(m.getKey(),m.getValue());
			}
		}
		return tempStr;
	}

	//String转bigdecimal
	public static BigDecimal[] formatIntegerArray(String str,String f){
		System.out.println(str);
		if(str.length()>2){
			String aaa=str.substring(str.length()-2, str.length()-1);
			System.out.println(aaa);
			if(aaa.equals(f)){
				str=str.substring(0, str.length()-1);
			}
		}

		String[] strArr = str.split(f); //然后使用split方法将字符串拆解到字符串数组中
		BigDecimal[] intArr = new BigDecimal[strArr.length]; //定义一个长度与上述的字符串数组长度相通的整型数组
		for(int a=0;a<strArr.length;a++){
			BigDecimal aa=new BigDecimal(strArr[a]);
			intArr[a] = aa; 
		}
		for(int a=0;a<intArr.length;a++){
			System.out.println(intArr[a]);
		}
		return intArr;
	}

	//去除数字小数点后多余的0,并转为百分比字符串，如“13.0”则返回“13%”
	public static String rvZeroAndDot(String s){  
		if (s.isEmpty()) {
			return "";
		}
		if(s.indexOf(".") > 0){  
			s = s.replaceAll("0+?$", "");//去掉多余的0  
			s = s.replaceAll("[.]$", "");//如最后一位是.则去掉  
		}  
		return s;  
	}

	//去除数字小数点后多余的0,并转为百分比字符串，如“13.0”则返回“13%”
	public static String rvZeroAndDot(BigDecimal num){  
		if (num==null) {
			return "";
		}
		String s = num.toString();
		if(s.indexOf(".") > 0){  
			s = s.replaceAll("0+?$", "");//去掉多余的0  
			s = s.replaceAll("[.]$", "");//如最后一位是.则去掉  
		}  
		return s;  
	}

	//去除数字小数点后多余的0,并转为百分比字符串，如“13.0”则返回“13%”
	public static String rvZeroAndDot1(String s){  
		if (s.isEmpty()) {
			return "";
		}
		if(s.indexOf(".") > 0){  
			s = s.replaceAll("0+?$", "");//去掉多余的0  
			s = s.replaceAll("[.]$", "");//如最后一位是.则去掉  
		}  
		return s+"%";  
	}

	/**
	 * 解析地址
	 * @param address
	 * @return
	 */
	public static Map<String,String> addressResolution(String address){
		Map<String,String> map = new LinkedHashMap<String,String>();
		if(address == null){
			return map;
		}
		String regex = "(?<province>[^省]+自治区|.*?省|.*?行政区|.*?市)(?<city>[^市]+自治州|.*?地区|.*?行政单位|.+盟|市辖区|.*?市|.*?县)(?<county>[^县]+县|.+区|.+市|.+旗|.+海域|.+岛)?(?<town>[^区]+区|.+镇)?(?<village>.*)";
		Matcher matcher = Pattern.compile(regex).matcher(address);
		while(matcher.find()){
			String province = matcher.group("province");
			String city = matcher.group("city");
			String county = matcher.group("county");
			String town = matcher.group("town");
			String village = matcher.group("village");
			map.put("province", province==null?"":province.trim());
            map.put("city", city==null?"":city.trim());
            map.put("county", county==null?"":county.trim());
            map.put("town", town==null?"":town.trim());
            map.put("village", village==null?"":village.trim());
		}
		return map;
	}
	
	/**
	 * 生成强随机密码
	 * @param pswdLen
	 * @return
	 */
	public static String getStrongPwd(int pswdLen){
		String[] pswdStr = {"qwertyuiopasdfghjklzxcvbnm","QWERTYUIOPASDFGHJKLZXCVBNM","0123456789","*()_"};
		char[] chs = new char[pswdLen];
		for(int i=0;i<pswdStr.length;i++){
			int idx = (int) (Math.random()*pswdStr[i].length());
			chs[i] = pswdStr[i].charAt(idx);
		}
		for(int i=pswdStr.length;i<pswdLen;i++){
			int arrIdx = (int)(Math.random()*pswdStr.length);
			int strIdx = (int)(Math.random()*pswdStr[arrIdx].length());
			chs[i] = pswdStr[arrIdx].charAt(strIdx);
		}
		for(int i=0;i<1000;i++){
			int idx1 = (int)(Math.random()*chs.length);
			int idx2 = (int)(Math.random()*chs.length);
			if(idx1 == idx2){
				continue;
			}
			char tempChar = chs[idx1];
			chs[idx1] = chs[idx2];
			chs[idx2] = tempChar;
		}
		return new String(chs);
	}
	
	/**
	 * 用于多字段分组
	 * @param value
	 * @param paras
	 * @return
	 */
	public static String format(String value,Object... paras) {
        return MessageFormat.format(value, paras);
    }
	
	//测试主函数
	public static void main(String[] arg) {
		//formatIntegerArray("123123;123;333",";");
		System.out.println(getStrongPwd(8));
	}
}